#include "directoryOperation.h"

int stackInit(pathStack_t* cur){
    char* path = (char*)calloc(1024,sizeof(char));
    char* p = getcwd(path,1024);
    if(p == NULL){
        perror("getcwd:");
        return -1;
    }
    cur->stack[(cur->top)++] = p;
    return 0;
}

int stackClean(pathStack_t* cur){
    for(int j = cur->top - 1;j >= 0;j--){
        free(cur->stack[j]);
    }
    cur->top = 0;
    return 0;
}

int stackRestore(pathStack_t* cur){
    memcpy(cur->stack,cur->restoreStack,sizeof(char*)*MAX_STACK_SIZE);
    cur->top = cur->top_r;
    return 0;
}

int stackPath(char* path,pathStack_t* cur){
    char* token;
    char* saveptr;
    char* str = strdup(path);
    memcpy(cur->restoreStack,cur->stack,sizeof(char*)*1024);
    cur->top_r = cur->top;
    for(int i = 0;;i++,str = NULL){
        token = strtok_r(str,"/",&saveptr);
        if(token == NULL){
            break;
        }
        if(strcmp(token,".") == 0){
            continue;
        }
        if(strcmp(token,"..") == 0){
            --(cur->top);
            if(cur->top == 0){
                printf("path invalid\n");
                stackRestore(cur);
                return -1;
            }
            continue;
        }
        char* p = (char*)calloc(256,sizeof(char));
        sprintf(p,"/%s",token);
        cur->stack[(cur->top)++] = p;
    }
    free(str);
    return 0;
} 

int pwd_client(char* path,pathStack_t* cur){
    for(int i = 1;i < cur->top;i++){
        strcat(path,cur->stack[i]);
    }
    return 0;
}

int pwd_server(char* path,pathStack_t* cur){
    for(int i = 0;i < cur->top;i++){
        strcat(path,cur->stack[i]);
    }
    return 0;
}

int pri_cd(bool path_type,char* path,pathStack_t* cur){
    memcpy(cur->restoreStack,cur->stack,sizeof(char*)*1024);
    cur->top_r = cur->top;
    if(path_type){
        if(cur->top != 1){
            cur->top = 1;
        }
        stackPath(path,cur);
        char p[1024] = {0};
        pwd_server(p,cur);
        int ret = access(p,F_OK);
        if(ret == -1){
            perror("directoty no exist:");
            stackRestore(cur);
            return -1;
        }
        return 0;
    }
    else{
        stackPath(path,cur);
        char p[1024] = {0};
        pwd_server(p,cur);
        int ret = access(p,F_OK);
        if(ret == -1){
            perror("directoty no exist:");
            stackRestore(cur);
            return -1;
        }
        return 0;
    }
}

int pri_mkdir(bool path_type,char* path,pathStack_t* cur){
    memcpy(cur->restoreStack,cur->stack,sizeof(char*)*1024);
    cur->top_r = cur->top;
    if(path_type){
        int ret = mkdir(path+1,0775);
        if(ret == -1){
            perror("mkdir:");
            return -1;
        }
        return 0;
    }
    else{
        stackPath(path,cur);
        --(cur->top);
        char p[1024] = {0};
        pwd_server(p,cur);
        int ret = access(p,F_OK);
        if(ret == -1){
            perror("path invalid:");
            stackRestore(cur);
            return -1;
        }
        cur->top++;
        char np[1024] = {0};
        pwd_server(np,cur);
        int ret2 = mkdir(np,0775);
        if(ret2 == -1){
            perror("mkdir:");
            stackRestore(cur);
            return -1;
        }
    }
    stackRestore(cur);
    return 0;
}

int pri_rmdir(bool path_type,char* path,pathStack_t* cur){
    memcpy(cur->restoreStack,cur->stack,sizeof(char*)*1024);
    cur->top_r = cur->top;
    if(path_type){
        int ret = rmdir(path+1);
        if(ret == -1){
            perror("rmdir:");
            return -1;
        }
        return 0;
    }
    else{
        stackPath(path,cur);
        char p[1024] = {0};
        pwd_server(p,cur);
        int ret = access(p,F_OK);
        if(ret == -1){
            perror("path invalid:");
            stackRestore(cur);
            return -1;
        }
        int ret2 = rmdir(p);
        if(ret2 == -1){
            perror("rmdir:");
            stackRestore(cur);
            return -1;
        }
        stackRestore(cur);
        return 0;
    }
}

int pri_ls(bool path_type,char* path,pathStack_t* cur,char* result){
    memcpy(cur->restoreStack,cur->stack,sizeof(char*)*1024);
    cur->top_r = cur->top;
    DIR* dir;
    if(path_type){
        dir = opendir(path+1);
        if(dir == NULL){
            perror("opendir:");
            return -1;
        }
    }
    else{
        stackPath(path,cur);
        char p[1024] = {0};
        pwd_server(p,cur);
        int ret = access(p,F_OK);
        if(ret == -1){
            perror("path invalid:");
            stackRestore(cur);
            return -1;
        }
        dir = opendir(p);
        if(dir == NULL){
            perror("opendir:");
            return -1;
        }
        stackRestore(cur);
    }
    struct dirent* dir_p = NULL;
    while((dir_p = readdir(dir)) != NULL){
        strcat(result,dir_p->d_name);
        strcat(result,"\t");
    }
    closedir(dir);
    return 0;
}
